package com.ttg.web.service.Impl;

import com.ttg.common.enums.AcctSubjectTypeEnum;
import com.ttg.common.utils.BigDecimalUtils;
import com.ttg.common.utils.IntegerUtil;
import com.ttg.model.dto.CMAcctAnalysisDTO;
import com.ttg.model.pojo.CostManageAcctDepositAnalysis;
import com.ttg.model.vo.CMAcctDepositAnalysisVO;
import com.ttg.web.service.AcctDepositAnalysisService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * Description：
 * Author: chenyou
 * Date: 2025/9/30 17:56
 * Company: ttg
 * Copyright: Copyright (c) 2025
 */
@Service
public class AcctDepositAnalysisServiceImpl implements AcctDepositAnalysisService {

    private static final int DIV_SCALE = 8;

    /**
     * 账户存款结构分解清算
     * @param reqDto 入参dto
     * @param settList 清算组数据
     * @param comparisonList 对照组数据
     * @param acctSubjectTypeEnum 账户类型枚举 0-对公户，1-个人户
     */
    @Override
    public CMAcctDepositAnalysisVO depositComparisonNetting(CMAcctAnalysisDTO reqDto, List<CostManageAcctDepositAnalysis> settList, List<CostManageAcctDepositAnalysis> comparisonList, AcctSubjectTypeEnum acctSubjectTypeEnum){
        Optional s1 = settList.stream().filter(o -> IntegerUtil.equals(acctSubjectTypeEnum.getValue(),o.getCmadAcctType())).findFirst();
        CostManageAcctDepositAnalysis settle = (CostManageAcctDepositAnalysis)s1.get();
        Optional c1 = comparisonList.stream().filter(o -> IntegerUtil.equals(acctSubjectTypeEnum.getValue(),o.getCmadAcctType())).findFirst();
        CostManageAcctDepositAnalysis comparison = (CostManageAcctDepositAnalysis)c1.get();

        CMAcctDepositAnalysisVO vo = new CMAcctDepositAnalysisVO();
        vo.setIntervalType(reqDto.getIntervalType());
        vo.setAcctDimType(reqDto.getAcctDimType());
        vo.setAcctType(acctSubjectTypeEnum.getValue());
        vo.setSettleYear(reqDto.getSettleYear());
        vo.setSettleMonth(reqDto.getSettleMonth());
        vo.setSettleLastdayAmt(settle.getCmadLastdayAmt());
        vo.setSettleAvgAmt(settle.getCmadAvgAmt());
        vo.setSettleWeightRate(settle.getCmadWeightRate());
        vo.setSettlePayInterest(settle.getCmadPayInterest());

        vo.setComparisonYear(reqDto.getComparisonYear());
        vo.setComparisonMonth(reqDto.getComparisonMonth());
        vo.setComparisonLastdayAmt(comparison.getCmadLastdayAmt());
        vo.setComparisonAvgAmt(comparison.getCmadAvgAmt());
        vo.setComparisonWeightRate(comparison.getCmadWeightRate());
        vo.setComparisonPayInterest(comparison.getCmadPayInterest());

        //期末时点轧差
        BigDecimal nettingLastdayAmt = nettingLastdayAmt(settle.getCmadLastdayAmt(),comparison.getCmadLastdayAmt());
        vo.setNettingLastdayAmt(nettingLastdayAmt);
        //期间日均轧差
        BigDecimal nettingAvgAmt = nettingAvgAmt(settle.getCmadAvgAmt(),comparison.getCmadAvgAmt());
        vo.setNettingAvgAmt(nettingAvgAmt);
        //模拟付息轧差
        BigDecimal nettingPayInterest = nettingPayInterest(settle.getCmadPayInterest(),comparison.getCmadPayInterest());
        vo.setNettingPayInterest(nettingPayInterest);
        //加权利率轧差
        BigDecimal nettingWeightRate = nettingWeightRate(nettingPayInterest,nettingAvgAmt);
        vo.setNettingWeightRate(nettingWeightRate);

        return vo;
    }

    /**
     * 账户存款结构分解清算-合计
     * 合计：个人户+对公户
     * @param a1 个人户
     * @param a2 对公户
     */
    @Override
    public CMAcctDepositAnalysisVO total(CMAcctAnalysisDTO reqDto,CMAcctDepositAnalysisVO a1, CMAcctDepositAnalysisVO a2) {
        CMAcctDepositAnalysisVO vo = new CMAcctDepositAnalysisVO();
        vo.setIntervalType(reqDto.getIntervalType());
        vo.setAcctDimType(reqDto.getAcctDimType());
        vo.setAcctType(2);
        vo.setSettleYear(reqDto.getSettleYear());
        vo.setSettleMonth(reqDto.getSettleMonth());
        vo.setSettleLastdayAmt(BigDecimalUtils.add(a1.getSettleLastdayAmt(),a2.getSettleLastdayAmt()));
        vo.setSettleAvgAmt(BigDecimalUtils.add(a1.getSettleAvgAmt(),a2.getSettleAvgAmt()));
        vo.setSettleWeightRate(BigDecimalUtils.add(a1.getSettleWeightRate(),a2.getSettleWeightRate()));
        vo.setSettlePayInterest(BigDecimalUtils.add(a1.getSettlePayInterest(),a2.getSettlePayInterest()));

        vo.setComparisonYear(reqDto.getComparisonYear());
        vo.setComparisonMonth(reqDto.getComparisonMonth());
        vo.setComparisonLastdayAmt(BigDecimalUtils.add(a1.getComparisonLastdayAmt(),a2.getComparisonLastdayAmt()));
        vo.setComparisonAvgAmt(BigDecimalUtils.add(a1.getComparisonAvgAmt(),a2.getComparisonAvgAmt()));
        vo.setComparisonWeightRate(BigDecimalUtils.add(a1.getComparisonWeightRate(),a2.getComparisonWeightRate()));
        vo.setComparisonPayInterest(BigDecimalUtils.add(a1.getComparisonPayInterest(),a2.getComparisonPayInterest()));

        vo.setNettingLastdayAmt(BigDecimalUtils.add(a1.getNettingLastdayAmt(),a2.getNettingLastdayAmt()));
        vo.setNettingAvgAmt(BigDecimalUtils.add(a1.getNettingAvgAmt(),a2.getNettingAvgAmt()));
        vo.setNettingPayInterest(BigDecimalUtils.add(a1.getNettingPayInterest(),a2.getNettingPayInterest()));
        vo.setNettingWeightRate(BigDecimalUtils.add(a1.getNettingWeightRate(),a2.getNettingWeightRate()));

        return vo;
    }

    /**
     * 期末时点轧差
     * 公式：清算期末时点 - 对照期末时点
     */
    public BigDecimal nettingLastdayAmt(BigDecimal settleLastdayAmt,BigDecimal comparisonLastdayAmt){
        return BigDecimalUtils.sub(settleLastdayAmt,comparisonLastdayAmt);
    }

    /**
     * 期间日均轧差
     * 公式：清算期间日均 - 对照期间日均
     */
    public BigDecimal nettingAvgAmt(BigDecimal settleAvgAmt,BigDecimal comparisonAvgAmt){
        return BigDecimalUtils.sub(settleAvgAmt,comparisonAvgAmt);
    }

    /**
     * 模拟付息轧差
     * 公式：清算模拟付息 - 对照模拟付息
     */
    public BigDecimal nettingPayInterest(BigDecimal settlePayInterest,BigDecimal comparisonPayInterest){
        return BigDecimalUtils.sub(settlePayInterest,comparisonPayInterest);
    }


    /**
     * 加权利率轧差
     * 公式：模拟付息/期间日均 * 100%
     */
    public BigDecimal nettingWeightRate(BigDecimal payInterestNetting,BigDecimal avgAmtNetting){
        return BigDecimalUtils.mul(BigDecimalUtils.div(payInterestNetting,avgAmtNetting,DIV_SCALE),100);
    }

}
